package org.commando.donquixote.erlmodleing;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import com.change_vision.jude.api.inf.exception.LicenseNotFoundException;
import com.change_vision.jude.api.inf.exception.NonCompatibleException;
import com.change_vision.jude.api.inf.exception.ProjectLockedException;
import com.change_vision.jude.api.inf.exception.ProjectNotFoundException;
import com.change_vision.jude.api.inf.model.IAttribute;
import com.change_vision.jude.api.inf.model.IClass;
import com.change_vision.jude.api.inf.model.IDiagram;
import com.change_vision.jude.api.inf.model.IInteraction;
import com.change_vision.jude.api.inf.model.ILifeline;
import com.change_vision.jude.api.inf.model.IMessage;
import com.change_vision.jude.api.inf.model.IModel;
import com.change_vision.jude.api.inf.model.INamedElement;
import com.change_vision.jude.api.inf.model.IOperation;
import com.change_vision.jude.api.inf.model.IPackage;
import com.change_vision.jude.api.inf.model.ISequenceDiagram;
import com.change_vision.jude.api.inf.project.ProjectAccessor;
import com.change_vision.jude.api.inf.project.ProjectAccessorFactory;

public class GenCode {
	static String FileName = "/home/donquixote/startree/doc/modle/modle.jude";
	static String ExportPath = ".";
	
	static HashMap<String, genModule> BuildList = new HashMap<String, genModule>();

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length > 0) {
			FileName = args[0];
		}
		
		if (args.length > 1) {
			ExportPath = args[1];
		}
		
		// TODO Auto-generated method stub
		ProjectAccessor prjAccessor = null;
		prjAccessor = ProjectAccessorFactory.getProjectAccessor();
		
	    try {
			try {
				prjAccessor.open(FileName, true, false, true);
			} catch (Throwable e) {
				System.out.println(String.format("文件%s无法访问，请确认文件是否存在或者有权限访问！", FileName));
				return;
			}
			
            // Get a project model
            IModel project = prjAccessor.getProject();
            // Display packages and classes
            procClassPackage(project, ExportPath);
            procSequPackage(project);
		} catch (Exception ex) {

			ex.printStackTrace();
		}
		Iterator it = BuildList.keySet().iterator();
		while(it.hasNext()){
			BuildList.get(it.next()).saveFile();
		}
		
	    prjAccessor.close();
	}
	
    private static void procClassPackage(IPackage iPackage, String Path) {

    	// Display packages and classes
        INamedElement[] iNamedElements = iPackage.getOwnedElements();
        for (int i = 0; i < iNamedElements.length; i++) {
            if (iNamedElements[i] instanceof IPackage) {
                IPackage iChildPackage = (IPackage) iNamedElements[i];
                // Display a package
                procClassPackage(iChildPackage, Path + "/" + iChildPackage.getName());
            } else if (iNamedElements[i] instanceof IClass) {
                IClass iClass = (IClass) iNamedElements[i];
                // Display a class
                procClass(iClass, Path);
            }
        }
    }
	
    private static void procSequPackage(IPackage iPackage) {

    	// Display packages and classes
    	IDiagram[] dgms = iPackage.getDiagrams();
        for (int i = 0; i < dgms.length; i++) {
            if (dgms[i] instanceof ISequenceDiagram) {
            	ISequenceDiagram isd = (ISequenceDiagram) dgms[i];
                // Display a class
                procInteraction(isd);
            }
        }

        INamedElement[] iNamedElements = iPackage.getOwnedElements();
        for (int i = 0; i < iNamedElements.length; i++) {
            if (iNamedElements[i] instanceof IPackage) {
                IPackage iChildPackage = (IPackage) iNamedElements[i];
                // Display a package
                procSequPackage(iChildPackage);
            }
        }
    }

    
    private static void procInteraction(ISequenceDiagram isd) {
    	ILifeline[] LifeLines =  isd.getInteraction().getLifelines();
    	for(int i = 0; i < LifeLines.length; i++){
    		String CalssName = LifeLines[i].getBase().getName().toLowerCase();

    		INamedElement[] Messages = LifeLines[i].getFragments();
    		for(int j = 0; j < Messages.length; j++){
    			if (Messages[j] instanceof IMessage){
    				IMessage Msg = (IMessage) Messages[j];
    				if (Msg.isAsynchronous()){
    			    	BuildList.get(CalssName).setASyncBool(Msg.getName(), true);
    				}
    			}
    			
    		}
    	}
	}

	private static void procClass(IClass iClass, String Path) {
    	genModule gm = new genModule(iClass.getName().toLowerCase(), Path);

        // Display all operations
        IOperation[] iOperations = iClass.getOperations();
        for (int i = 0; i < iOperations.length; i++) {
        	int Plen = iOperations[i].getParameters().length;
        	
        	Operator Opt = new Operator(iOperations[i].getName());
        	for(int j = 0; j < Plen; j++){
        		String ParamtName = iOperations[i].getParameters()[j].getName();
        		Opt.addParam(ParamtName.toUpperCase());
        	}
        	
        	gm.addOperator(Opt);
        }
    	BuildList.put(iClass.getName().toLowerCase(), gm);
    }
}
